package com.szp.lagou.neo4j.neo4jdemo.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.szp.lagou.neo4j.neo4jdemo.entity.Fatherof;
import com.szp.lagou.neo4j.neo4jdemo.entity.Friend;
import com.szp.lagou.neo4j.neo4jdemo.entity.Motherof;
import com.szp.lagou.neo4j.neo4jdemo.entity.Person;
import com.szp.lagou.neo4j.neo4jdemo.repository.PersonRepository;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class PersonService {
    private final static Logger LOG = LoggerFactory.getLogger(PersonService.class);

	private final PersonRepository personRepository;
	public PersonService(PersonRepository personRepository) {
		this.personRepository = personRepository;
	}

    @Transactional(readOnly = true)
	public Map<String, Object>  graph(int limit) {
        
        Collection<Person> result = personRepository.graph();
        LOG.info("{}", result);
		return toD3Format(result);
    }
    
    private Map<String, Object> toD3Format(Collection<Person> movies) {
        // List<Map<String, Object>> nodes = new ArrayList<>();
        Map<String,Object> nodes = new HashMap<>();
		List<Map<String, Object>> rels = new ArrayList<>();
		Iterator<Person> result = movies.iterator();
		while (result.hasNext()) {
            Person person = result.next();
            nodes.put(person.getPid() + "", map("name", person.getName(), "type", "person"));
			if(person.getRoles() != null){
                for (Friend role : person.getRoles()) {
                    Person startPerson = role.getStartPerson();
                    Person endPerson = role.getEndPerson();

                    rels.add(getRelation(startPerson,endPerson, "Friend"));
                }
            }
            if(person.getMotherof() != null){
                for (Motherof role : person.getMotherof()) {
                    Person startPerson = role.getStartPerson();
                    Person endPerson = role.getEndPerson();

                    rels.add(getRelation(startPerson,endPerson, "Mother"));
                }
            }
            if(person.getFatherof() != null){
                for (Fatherof role : person.getFatherof()) {
                    Person startPerson = role.getStartPerson();
                    Person endPerson = role.getEndPerson();

                    rels.add(getRelation(startPerson,endPerson, "Son"));
                }
            }
		}
		return map("nodes", nodes, "links", rels);
    }

    private Map<String,Object> getRelation(Person startPerson, Person endPerson, String relationship){
        Map<String,Object> rel = new HashMap<>();
        rel.put("source", startPerson.getPid());
        rel.put("target", endPerson.getPid());
        rel.put("rela", relationship);
        rel.put("type", "Friend");
        return rel;
    }
    
    private Map<String, Object> map(String key1, Object value1, String key2, Object value2) {
		Map<String, Object> result = new HashMap<String, Object>(2);
		result.put(key1, value1);
		result.put(key2, value2);
		return result;
	}
}